<?php
/**
 * Displays a handy input for phone numbers, the countrycode is a select list with spoofing
 * protection. The countrycodes must be an array of Countrycode active record objects.
 *
 * @author Niels Janssen
 * @since 2008-10-17
 * @copyright 2008 AdamsYoung
 */
class PhonenumberInput extends FormElement {

	/**
	 * The constructor.
	 *
	 * @param String $name
	 * @param array( Countrycode... ) $countrycodes
	 * @param int $countrycode
	 * @param int $areacode
	 * @param int $number
	 */
	function __construct( $name, $label, array $countrycodes, $countrycode = null, $areacode = null, $number = null ) {

		$countrycodeCopy = $countrycode;
		$areacodeCopy = $areacode;
		$numberCopy = $number;

		$countrycode = array_key_exists( $name . '_country', $_POST ) ? $_POST[ $name . '_country'] : null;

		if( empty( $countrycode ) )
			$countrycode = 31;

		if ($countrycodeCopy != null){
			$countrycode = $countrycodeCopy;
		}

		$areacode = array_key_exists( $name . '_area', $_POST ) ? $_POST[ $name . '_area' ] : '';
		if ($areacodeCopy != null) {
			$areacode = $areacodeCopy;
		}

		$number = array_key_exists( $name , $_POST ) ? $_POST[ $name ] : '';

		if ($numberCopy != null) {
			$number = $numberCopy;
		}

		parent::__construct( $name, array(
			'countrycodes' => $countrycodes,
			'countrycode' => $countrycode,
			'areacode' => $areacode,
			'number' => $number,
			'value' => '+' . $countrycode . '-' . ( ( substr( $areacode, 0, 1 ) == '0' ) ? substr( $areacode, 1 ) : $areacode ) . '-' . $number,
			'label' => $label
		) );
	}

	/**
	 * Checks if the element is valid. It sets a few validation rules of its own to make sure it is a valid telephone number.
	 *
	 * @return boolean
	 */
	public function isValid() {
		if( $this->validator == null ) {
			$this->getValidator();
		}

		if( substr( $this->getProperty('value'), strlen( $this->getProperty('value')) - 2, 2 ) == '--' ) {
			$this->setProperties(array( 'value' => '' ));
		}

		$this->validator->removeRulesByType( ElementValidation::REGEX_MATCH );
		$this->validator->compareMatch( ElementValidation::REGEX_PHONE_NUMBER, '##invalid_phone_number##' );
		$this->validator->method( array( $this, 'validateCountryCode' ), '##invalid_countrycode_no_spoofing##' );

		try {
			$this->validator->validate ( $this );
		} catch ( ElementValidationException $e ) {
			$this->errorFound = true;
			$this->errorMessage = $e->getMessage ();
			return false;
		}

		return true;
	}

	/**
	 * Validates the countrycode that was entered to prevent spoofing. It is called by the validator
	 * and must never be called directly.
	 *
	 * @param PhonenumberInput $pi
	 * @return boolean
	 */
	public function validateCountryCode( PhonenumberInput $pi ) {
		foreach( $this->getProperty('countrycodes') as $country ) {
			if( $country->dialcode == $this->getProperty('countrycode') ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * A magic method used by the validator to check if an entity is empty.
	 *
	 * @return boolean
	 */
	public function isEmpty() {
		$countrycode = $this->getProperty('countrycode');
		$areacode = $this->getProperty('areacode');
		$number = $this->getProperty('number');

		return empty( $countrycode ) || empty( $areacode ) || empty( $number );
	}

	/**
	 * Returns an array with the seperate parts of the telephone number.
	 *
	 * @return array
	 */
	public function getValues() {
		return array( 'countrycode' => $this->getProperty('countrycode'), 'areacode' => $this->getProperty('areacode'), 'number' => $this->getProperty('number') );
	}

	/**
	 * Generates the HTML for this element.
	 *
	 * @return String
	 */
	public function __toString() {
		$return = '
		<div class="form phonenumberinput ' . $this->getProperty('class') . '">
			<label>' . $this->getProperty('label') . '</label>
			<select id="' . $this->name . '_countrycode" name="' . $this->name . '_country">';

		foreach( $this->getProperty( 'countrycodes' ) as $countrycode ) {
			$return .= '				<option value="' . $countrycode->dialcode . '"' . ( $countrycode->dialcode == $this->getProperty('countrycode') ? ' selected="selected"' : '' ) . '>' . ( $countrycode->cn_nl ? $countrycode->cn_nl : $countrycode->cn ) . ' (+' . $countrycode->dialcode . ')</option>';
		}

		$return .= '
			</select>
			-
			<input type="text" size="2" class="phonenumberinput_areacode" name="' . $this->name . '_area" id="' . $this->name . '_areacode" value="' . $this->getProperty('areacode') . '" />
			-
			<input type="text" size="4" class="phonenumberinput_number" name="' . $this->name . '" id="' . $this->name . '_" value="' . $this->getProperty('number') . '" />
			' . ( $this->inAJAXMode() || !empty( $this->errorMessage ) ? '<div class="error' . ( $this->inAJAXMode() ? ' ajax' : '' ) . '" id="' . ( $this->getFormName() != '' ? $this->getFormName() . '_' : '' ) . $this->name . '_error">' . $this->errorMessage . '</div>' : '' ) . '
		</div>';

		return $return;
	}
}